package com.shell.scheduler;

import com.shell.scheduler.job.po.SchdJob;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;

public class SchedulerManager {
	private static final Log logger = LogFactory.getLog(SchedulerManager.class);
	static Scheduler scheduler;

	private static JobDetail getJobDetail(String jobCode) {
		return JobBuilder.newJob(JobExecutor.class).withIdentity(jobCode, "SCHE_JOB_GROUP").build();
	}

	private static JobKey getJobKey(String jobCode) {
		return new JobKey(jobCode, "SCHE_JOB_GROUP");
	}

	private static Trigger getTrigger(String jobCode, CronScheduleBuilder scheduleBuilder) {
		return TriggerBuilder.newTrigger().withIdentity(jobCode, "SCHE_TRIGGER_GROUP").withSchedule(scheduleBuilder)
				.build();
	}

	public static void addJobs(List<SchdJob> jobs) {
		for (SchdJob job : jobs) {
			addJob(job);
		}
	}

	public static void addJob(SchdJob job) {
		try {
			String jobCode = job.getJobCode();

			JobKey jobKey = getJobKey(jobCode);
			boolean exists = scheduler.checkExists(jobKey);

			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getJobTime());
			Trigger trigger = getTrigger(jobCode, scheduleBuilder);
			TriggerKey triggerKey = trigger.getKey();
			if (!exists) {
				JobDetail jobDetail = getJobDetail(jobCode);
				jobDetail.getJobDataMap().put("SCHE_JOB", job);
				scheduler.scheduleJob(jobDetail, trigger);
			} else {
				scheduler.rescheduleJob(triggerKey, trigger);
			}
		} catch (org.quartz.SchedulerException e) {
			logger.error(job.getJobName() + " add error.", e);
		}
	}

	public static void triggerJob(String jobCode, Map<String, String> params) {
		try {
			JobKey jobKey = getJobKey(jobCode);
			JobDetail jobDetail = scheduler.getJobDetail(jobKey);
			if ((params != null) && (!params.isEmpty())) {
				jobDetail.getJobDataMap().put("JOB_PARAMS", params);
			}
			scheduler.triggerJob(jobKey);
		} catch (org.quartz.SchedulerException e) {
			logger.error(jobCode + " trigger error.", e);
			throw new SchedulerException(jobCode + " trigger error.", e);
		}
	}

	public static void triggerJob(String jobCode) {
		triggerJob(jobCode, null);
	}

	public static void deleteJob(String jobCode) {
		try {
			JobKey jobKey = getJobKey(jobCode);

			scheduler.pauseJob(jobKey);
			scheduler.deleteJob(jobKey);
		} catch (org.quartz.SchedulerException e) {
			logger.error(jobCode + " delete error.", e);
			throw new SchedulerException(jobCode + " delete error.", e);
		}
	}

	public static void pauseJob(String jobCode) {
		try {
			JobKey jobKey = getJobKey(jobCode);

			scheduler.pauseJob(jobKey);
		} catch (org.quartz.SchedulerException e) {
			logger.error(jobCode + " pause error.", e);
			throw new SchedulerException(jobCode + " pause error.", e);
		}
	}

	public static void resumeJob(String jobCode) {
		try {
			JobKey jobKey = getJobKey(jobCode);

			scheduler.resumeJob(jobKey);
		} catch (org.quartz.SchedulerException e) {
			logger.error(jobCode + " resume error.", e);
			throw new SchedulerException(jobCode + " resume error.", e);
		}
	}

	public static void start() {
		try {
			if (!scheduler.isStarted()) {
				scheduler.start();
			}
		} catch (org.quartz.SchedulerException e) {
			e.printStackTrace();
			throw new SchedulerException("Start Jobs Error.", e);
		}
	}

	public static void shutdown() {
		try {
			if (!scheduler.isShutdown()) {
				scheduler.shutdown();
			}
		} catch (org.quartz.SchedulerException e) {
			e.printStackTrace();
			throw new SchedulerException("Shutdown Jobs Error.", e);
		}
	}
}